<?php
declare (strict_types = 1);

namespace app\common\service;

use think\Exception;
use think\Db;

/**
 * 停车场API服务类
 * Class ParkingApiService
 * @package app\common\service
 */
class ParkingApiService
{
    protected $apiUrl;
    protected $appId;
    protected $appSecret;
    protected $token;
    
    /**
     * 构造函数
     */
    public function __construct()
    {
        // 从配置中获取API参数
        $this->apiUrl = config('api_conf.api_url') ?: 'http://api.parking.example.com';
        $this->appId = config('wx_conf.appid') ?: 'demo_app_id';
        $this->appSecret = config('wx_conf.appSecret') ?: 'demo_app_secret';
        
        // 获取令牌
        $this->token = $this->getToken();
    }
    
    /**
     * 测试API连接
     * @return array
     */
    public function testConnection()
    {
        try {
            // 模拟API测试
            return [
                'success' => true,
                'message' => '连接成功',
                'data' => [
                    'api_version' => '1.0',
                    'server_time' => date('Y-m-d H:i:s'),
                    'status' => 'online'
                ]
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '连接失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 获取停车场信息
     * @param int $parkId 停车场ID
     * @return array
     */
    public function getParkInfo($parkId)
    {
        try {
            // 从数据库获取停车场信息
            $parkInfo = Db::name('parking_lots')->where('id', $parkId)->find();
            
            if (!$parkInfo) {
                return [
                    'success' => false,
                    'message' => '停车场不存在',
                    'data' => null
                ];
            }
            
            // 从第三方请求得到真实车场数据
            $apiUrl = $this->apiUrl;
            $params = [
                'org_id' => config('api_conf.org_id'),
                'org_secret' => config('api_conf.org_secret'),
                'park_id' => $parkId,
            ];
            $response = $this->sendRequest('POST', $apiUrl, $params);
            if (!$response['success']) {
                return $response;
            }
            $data = $response['data'];
            $parkInfo = [
                'id' => $data['park_id'],
                'name' => $data['park_name'],
                'company' => $data['company_name'],
                'address' => $data['address'],
                'contact_phone' => $data['contact_phone'],
                'status' => $data['status'],
                'create_time' => strtotime($data['create_time']),
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '获取停车场信息失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 获取车位信息
     * @param int $parkId 停车场ID
     * @return array
     */
    public function getSpaceInfo($parkId)
    {
        try {
            // 从数据库获取停车场信息
            $parkInfo = Db::name('parking_lots')->where('id', $parkId)->find();
            
            if (!$parkInfo) {
                return [
                    'success' => false,
                    'message' => '停车场不存在',
                    'data' => null
                ];
            }
            
            // 获取车位统计信息
            $totalSpace = $parkInfo['total_spaces'] ?? 0;
            $emptySpace = $parkInfo['available_spaces'] ?? 0;
            
            // 模拟API返回数据
            return [
                'success' => true,
                'message' => '获取成功',
                'data' => [
                    'park_id' => $parkInfo['id'],
                    'total_space' => $totalSpace,
                    'empty_space' => $emptySpace,
                    'occupied_space' => $totalSpace - $emptySpace,
                    'update_time' => date('Y-m-d H:i:s')
                ]
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '获取车位信息失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 获取停车记录
     * @param int $parkId 停车场ID
     * @param string $startTime 开始时间
     * @param string $endTime 结束时间
     * @return array
     */
    public function getParkingRecords($parkId, $startTime = '', $endTime = '')
    {
        try {
            // 构建查询条件
            $where = ['lot_id' => $parkId];
            
            if (!empty($startTime)) {
                $where[] = ['entry_time', '>=', strtotime($startTime)];
            }
            
            if (!empty($endTime)) {
                $where[] = ['exit_time', '<=', strtotime($endTime)];
            }
            
            // 从数据库获取停车记录
            $records = Db::name('parking_records')
                ->where($where)
                ->order('id', 'desc')
                ->limit(100)
                ->select();
            
            // 处理记录数据
            $data = [];
            foreach ($records as $record) {
                $data[] = [
                    'record_id' => $record['id'],
                    'plate_number' => $record['plate_number'] ?? '',
                    'entry_time' => !empty($record['entry_time']) ? date('Y-m-d H:i:s', $record['entry_time']) : '',
                    'exit_time' => !empty($record['exit_time']) ? date('Y-m-d H:i:s', $record['exit_time']) : '',
                    'duration' => !empty($record['exit_time']) && !empty($record['entry_time']) ? 
                        $record['exit_time'] - $record['entry_time'] : 0,
                    'fee' => $record['fee'] ?? 0,
                    'status' => !empty($record['exit_time']) ? 'completed' : 'parking'
                ];
            }
            
            return [
                'success' => true,
                'message' => '获取成功',
                'data' => $data
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '获取停车记录失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 获取API令牌
     * @return string
     */
    protected function getToken()
    {
        // 模拟获取令牌
        // 实际应用中应该调用API获取令牌并缓存
        return md5($this->appId . $this->appSecret . time());
    }
    
    /**
     * 发送API请求
     * @param string $method 请求方法
     * @param string $url 请求URL
     * @param array $params 请求参数
     * @return array
     */
    protected function sendRequest($method, $url, $params = [])
    {
        try {
            // 添加通用参数
            $params['app_id'] = $this->appId;
            $params['timestamp'] = time();
            $params['sign'] = $this->generateSign($params);
            
            // 初始化curl
            $ch = curl_init();
            
            // 设置curl选项
            curl_setopt_array($ch, [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_CONNECTTIMEOUT => 10,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json',
                    'User-Agent: ParkingAPI/1.0'
                ]
            ]);
            
            // 根据请求方法设置参数
            if (strtoupper($method) === 'POST') {
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
            } else {
                $url .= '?' . http_build_query($params);
                curl_setopt($ch, CURLOPT_URL, $url);
            }
            
            // 执行请求
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);
            
            // 检查curl错误
            if ($error) {
                return [
                    'success' => false,
                    'message' => 'CURL错误: ' . $error,
                    'data' => null
                ];
            }
            
            // 检查HTTP状态码
            if ($httpCode !== 200) {
                return [
                    'success' => false,
                    'message' => 'HTTP错误: ' . $httpCode,
                    'data' => null
                ];
            }
            
            // 解析响应
            $data = json_decode($response, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                return [
                    'success' => false,
                    'message' => 'JSON解析错误: ' . json_last_error_msg(),
                    'data' => null
                ];
            }
            
            return [
                'success' => true,
                'message' => '请求成功',
                'data' => $data
            ];
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '请求异常: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 发送API请求（兼容旧方法）
     * @param string $endpoint API端点
     * @param array $params 请求参数
     * @param string $method 请求方法
     * @return array
     */
    protected function request($endpoint, $params = [], $method = 'GET')
    {
        // 构建请求URL
        $url = rtrim($this->apiUrl, '/') . '/' . ltrim($endpoint, '/');
        
        return $this->sendRequest($method, $url, $params);
    }
    
    /**
     * 同步车场信息
     * @param int $parkId 停车场ID（可选，不传则同步所有）
     * @return array
     */
    public function syncParkInfo($parkId = null)
    {
        try {
            // 构建API请求参数
            $apiUrl = $this->apiUrl . '/park/list';
            $params = [
                'org_id' => config('api_conf.org_id'),
                'org_secret' => config('api_conf.org_secret'),
            ];
            
            if ($parkId) {
                $params['park_id'] = $parkId;
            }
            
            // 发送API请求获取车场信息
            $response = $this->sendRequest('POST', $apiUrl, $params);
            
            if (!$response['success']) {
                return [
                    'success' => false,
                    'message' => '获取车场信息失败: ' . $response['message'],
                    'data' => null
                ];
            }
            
            $parkList = $response['data']['park_list'] ?? [];
            $syncCount = 0;
            $errorList = [];
            
            // 开始事务
            Db::startTrans();
            
            foreach ($parkList as $parkData) {
                try {
                    // 检查车场是否已存在
                    $existPark = Db::name('parking_lots')
                        ->where('external_id', $parkData['park_id'])
                        ->find();
                    
                    // 准备车场数据
                    $data = [
                        'name' => $parkData['park_name'] ?? '',
                        'external_id' => $parkData['park_id'],
                        'company' => $parkData['company_name'] ?? '',
                        'address' => $parkData['address'] ?? '',
                        'contact_phone' => $parkData['contact_phone'] ?? '',
                        'city' => $parkData['city'] ?? '',
                        'district' => $parkData['district'] ?? '',
                        'longitude' => $parkData['longitude'] ?? 0,
                        'latitude' => $parkData['latitude'] ?? 0,
                        'total_spaces' => $parkData['total_spaces'] ?? 0,
                        'available_spaces' => $parkData['available_spaces'] ?? 0,
                        'status' => $parkData['status'] ?? 1,
                        'updated_at' => time()
                    ];
                    
                    if ($existPark) {
                        // 更新现有车场
                        Db::name('parking_lots')
                            ->where('id', $existPark['id'])
                            ->update($data);
                    } else {
                        // 新增车场
                        $data['created_at'] = time();
                        Db::name('parking_lots')->insert($data);
                    }
                    
                    $syncCount++;
                    
                } catch (Exception $e) {
                    $errorList[] = [
                        'park_id' => $parkData['park_id'] ?? 'unknown',
                        'error' => $e->getMessage()
                    ];
                }
            }
            
            // 提交事务
            Db::commit();
            
            return [
                'success' => true,
                'message' => "同步完成，成功同步 {$syncCount} 个车场",
                'data' => [
                    'sync_count' => $syncCount,
                    'error_count' => count($errorList),
                    'errors' => $errorList
                ]
            ];
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            
            return [
                'success' => false,
                'message' => '同步车场信息失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 同步车位实时信息
     * @param int $parkId 停车场ID
     * @return array
     */
    public function syncSpaceInfo($parkId)
    {
        try {
            // 构建API请求参数
            $apiUrl = $this->apiUrl . '/space/realtime';
            $params = [
                'org_id' => config('api_conf.org_id'),
                'org_secret' => config('api_conf.org_secret'),
                'park_id' => $parkId
            ];
            
            // 发送API请求
            $response = $this->sendRequest('POST', $apiUrl, $params);
            
            if (!$response['success']) {
                return [
                    'success' => false,
                    'message' => '获取车位信息失败: ' . $response['message'],
                    'data' => null
                ];
            }
            
            $spaceData = $response['data'];
            
            // 更新本地车场车位信息
            $updateData = [
                'total_spaces' => $spaceData['total_spaces'] ?? 0,
                'available_spaces' => $spaceData['available_spaces'] ?? 0,
                'occupied_spaces' => $spaceData['occupied_spaces'] ?? 0,
                'updated_at' => time()
            ];
            
            $result = Db::name('parking_lots')
                ->where('external_id', $parkId)
                ->update($updateData);
            
            if ($result) {
                return [
                    'success' => true,
                    'message' => '车位信息同步成功',
                    'data' => $updateData
                ];
            } else {
                return [
                    'success' => false,
                    'message' => '车场不存在或更新失败',
                    'data' => null
                ];
            }
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '同步车位信息失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 同步停车记录
     * @param int $parkId 停车场ID
     * @param string $startTime 开始时间
     * @param string $endTime 结束时间
     * @return array
     */
    public function syncParkingRecords($parkId, $startTime = '', $endTime = '')
    {
        try {
            // 构建API请求参数
            $apiUrl = $this->apiUrl . '/records/list';
            $params = [
                'org_id' => config('api_conf.org_id'),
                'org_secret' => config('api_conf.org_secret'),
                'park_id' => $parkId
            ];
            
            if ($startTime) {
                $params['start_time'] = $startTime;
            }
            if ($endTime) {
                $params['end_time'] = $endTime;
            }
            
            // 发送API请求
            $response = $this->sendRequest('POST', $apiUrl, $params);
            
            if (!$response['success']) {
                return [
                    'success' => false,
                    'message' => '获取停车记录失败: ' . $response['message'],
                    'data' => null
                ];
            }
            
            $records = $response['data']['records'] ?? [];
            $syncCount = 0;
            $errorList = [];
            
            // 获取本地车场ID
            $localPark = Db::name('parking_lots')
                ->where('external_id', $parkId)
                ->find();
            
            if (!$localPark) {
                return [
                    'success' => false,
                    'message' => '本地车场不存在，请先同步车场信息',
                    'data' => null
                ];
            }
            
            // 开始事务
            Db::startTrans();
            
            foreach ($records as $recordData) {
                try {
                    // 检查记录是否已存在
                    $existRecord = Db::name('parking_records')
                        ->where('external_id', $recordData['record_id'])
                        ->find();
                    
                    // 准备记录数据
                    $data = [
                        'lot_id' => $localPark['id'],
                        'external_id' => $recordData['record_id'],
                        'plate_number' => $recordData['plate_number'] ?? '',
                        'entry_time' => !empty($recordData['entry_time']) ? strtotime($recordData['entry_time']) : 0,
                        'exit_time' => !empty($recordData['exit_time']) ? strtotime($recordData['exit_time']) : 0,
                        'fee' => $recordData['fee'] ?? 0,
                        'payment_status' => $recordData['payment_status'] ?? 0,
                        'updated_at' => time()
                    ];
                    
                    if ($existRecord) {
                        // 更新现有记录
                        Db::name('parking_records')
                            ->where('id', $existRecord['id'])
                            ->update($data);
                    } else {
                        // 新增记录
                        $data['created_at'] = time();
                        Db::name('parking_records')->insert($data);
                    }
                    
                    $syncCount++;
                    
                } catch (Exception $e) {
                    $errorList[] = [
                        'record_id' => $recordData['record_id'] ?? 'unknown',
                        'error' => $e->getMessage()
                    ];
                }
            }
            
            // 提交事务
            Db::commit();
            
            return [
                'success' => true,
                'message' => "同步完成，成功同步 {$syncCount} 条记录",
                'data' => [
                    'sync_count' => $syncCount,
                    'error_count' => count($errorList),
                    'errors' => $errorList
                ]
            ];
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            
            return [
                'success' => false,
                'message' => '同步停车记录失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 批量同步所有数据
     * @return array
     */
    public function syncAllData()
    {
        try {
            $results = [];
            
            // 1. 同步车场信息
            $parkResult = $this->syncParkInfo();
            $results['park_sync'] = $parkResult;
            
            if (!$parkResult['success']) {
                return [
                    'success' => false,
                    'message' => '车场信息同步失败',
                    'data' => $results
                ];
            }
            
            // 2. 获取所有车场并同步车位信息
            $parks = Db::name('parking_lots')
                ->where('status', 1)
                ->field('id,external_id,name')
                ->select();
            
            $spaceResults = [];
            foreach ($parks as $park) {
                $spaceResult = $this->syncSpaceInfo($park['external_id']);
                $spaceResults[] = [
                    'park_name' => $park['name'],
                    'result' => $spaceResult
                ];
            }
            $results['space_sync'] = $spaceResults;
            
            // 3. 同步最近的停车记录（最近7天）
            $recordResults = [];
            $startTime = date('Y-m-d H:i:s', strtotime('-7 days'));
            $endTime = date('Y-m-d H:i:s');
            
            foreach ($parks as $park) {
                $recordResult = $this->syncParkingRecords($park['external_id'], $startTime, $endTime);
                $recordResults[] = [
                    'park_name' => $park['name'],
                    'result' => $recordResult
                ];
            }
            $results['record_sync'] = $recordResults;
            
            return [
                'success' => true,
                'message' => '批量同步完成',
                'data' => $results
            ];
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => '批量同步失败: ' . $e->getMessage(),
                'data' => null
            ];
        }
    }
    
    /**
     * 生成签名
     * @param array $params 请求参数
     * @return string
     */
    protected function generateSign($params)
    {
        // 排序参数
        ksort($params);
        
        // 构建签名字符串
        $signStr = '';
        foreach ($params as $key => $value) {
            if ($key != 'sign' && !is_array($value)) {
                $signStr .= $key . '=' . $value . '&';
            }
        }
        $signStr .= 'app_secret=' . $this->appSecret;
        
        // 生成签名
        return md5($signStr);
    }
}